package com.uniflow.service;

import com.uniflow.common.PageResult;
import com.uniflow.entity.Organization;
import com.uniflow.mapper.OrganizationMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 组织架构服务类
 */
@Service
@Transactional
public class OrganizationService {
    
    @Autowired
    private OrganizationMapper organizationMapper;
    
    /**
     * 分页查询组织列表
     */
    public PageResult<Organization> getOrganizationList(int pageNum, int pageSize, String parentId, String keyword) {
        List<Organization> organizations = organizationMapper.selectList(parentId, keyword);
        Long totalCount = organizationMapper.selectCount(parentId, keyword);
        int total = totalCount != null ? totalCount.intValue() : 0;
        
        // 手动分页
        int fromIndex = (pageNum - 1) * pageSize;
        int toIndex = Math.min(fromIndex + pageSize, organizations.size());
        List<Organization> pagedOrganizations = fromIndex < organizations.size() ? 
             organizations.subList(fromIndex, toIndex) : new ArrayList<Organization>();
         
         return new PageResult<Organization>(pageNum, pageSize, (long)organizations.size(), pagedOrganizations);
    }
    
    /**
     * 获取组织树结构
     */
    public List<Organization> getOrganizationTree() {
        List<Organization> allOrganizations = organizationMapper.selectAll();
        return buildTree(allOrganizations, null);
    }
    
    /**
     * 构建组织树
     */
    private List<Organization> buildTree(List<Organization> allOrganizations, String parentId) {
        return allOrganizations.stream()
                .filter(org -> Objects.equals(org.getParentId(), parentId))
                .peek(org -> {
                    List<Organization> children = buildTree(allOrganizations, org.getId());
                    org.setChildren(children);
                })
                .sorted(Comparator.comparing(Organization::getSortOrder, Comparator.nullsLast(Comparator.naturalOrder())))
                .collect(Collectors.toList());
    }
    
    /**
     * 获取根组织列表
     */
    public List<Organization> getRootOrganizations() {
        return organizationMapper.selectRootOrganizations();
    }
    
    /**
     * 根据ID查询组织
     */
    public Organization getOrganizationById(String id) {
        return organizationMapper.selectById(id);
    }
    
    /**
     * 根据名称查询组织
     */
    public Organization getOrganizationByName(String name) {
        return organizationMapper.selectByName(name);
    }
    
    /**
     * 根据外部ID查询组织
     */
    public Organization getOrganizationByExternalId(String externalId, String syncSource) {
        return organizationMapper.selectByExternalId(externalId, syncSource);
    }
    
    /**
     * 查询组织及其父级信息
     */
    public Organization getOrganizationWithParent(String id) {
        return organizationMapper.selectWithParent(id);
    }
    
    /**
     * 查询组织及其子级信息
     */
    public Organization getOrganizationWithChildren(String id) {
        return organizationMapper.selectWithChildren(id);
    }
    
    /**
     * 查询组织及其负责人信息
     */
    public Organization getOrganizationWithManager(String id) {
        return organizationMapper.selectWithManager(id);
    }
    
    /**
     * 创建组织
     */
    public Organization createOrganization(Organization organization) {
        // 生成ID
        organization.setId(UUID.randomUUID().toString().replace("-", ""));
        
        // 设置创建时间
        LocalDateTime now = LocalDateTime.now();
        organization.setCreatedAt(now);
        organization.setUpdatedAt(now);
        
        // 检查名称是否重复
        if (organizationMapper.existsByName(organization.getName(), organization.getParentId(), null)) {
            throw new RuntimeException("组织名称已存在");
        }
        
        // 设置排序号
        if (organization.getSortOrder() == null) {
            organization.setSortOrder(0);
        }
        
        organizationMapper.insert(organization);
        return organization;
    }
    
    /**
     * 批量创建组织
     */
    public List<Organization> createOrganizations(List<Organization> organizations) {
        LocalDateTime now = LocalDateTime.now();
        
        for (Organization organization : organizations) {
            organization.setId(UUID.randomUUID().toString().replace("-", ""));
            organization.setCreatedAt(now);
            organization.setUpdatedAt(now);
            
            if (organization.getSortOrder() == null) {
                organization.setSortOrder(0);
            }
        }
        
        organizationMapper.insertBatch(organizations);
        return organizations;
    }
    
    /**
     * 更新组织
     */
    public Organization updateOrganization(Organization organization) {
        Organization existingOrg = organizationMapper.selectById(organization.getId());
        if (existingOrg == null) {
            throw new RuntimeException("组织不存在");
        }
        
        // 检查名称是否重复（排除自己）
        if (StringUtils.hasText(organization.getName()) && 
            !organization.getName().equals(existingOrg.getName()) &&
            organizationMapper.existsByName(organization.getName(), organization.getParentId(), organization.getId())) {
            throw new RuntimeException("组织名称已存在");
        }
        
        // 检查是否形成循环引用
        if (StringUtils.hasText(organization.getParentId()) && 
            !organization.getParentId().equals(existingOrg.getParentId())) {
            if (isCircularReference(organization.getId(), organization.getParentId())) {
                throw new RuntimeException("不能将组织移动到其子组织下");
            }
        }
        
        organization.setUpdatedAt(LocalDateTime.now());
        organizationMapper.updateById(organization);
        
        return organizationMapper.selectById(organization.getId());
    }
    
    /**
     * 检查是否形成循环引用
     */
    private boolean isCircularReference(String orgId, String newParentId) {
        if (orgId.equals(newParentId)) {
            return true;
        }
        
        List<String> descendantIds = organizationMapper.selectDescendantIds(orgId);
        return descendantIds.contains(newParentId);
    }
    
    /**
     * 删除组织
     */
    public void deleteOrganization(String id) {
        Organization organization = organizationMapper.selectById(id);
        if (organization == null) {
            throw new RuntimeException("组织不存在");
        }
        
        // 检查是否有子组织
        if (organizationMapper.hasChildren(id)) {
            throw new RuntimeException("该组织下存在子组织，无法删除");
        }
        
        // 检查是否有用户
        Long userCountLong = organizationMapper.selectUserCount(id);
        int userCount = userCountLong != null ? userCountLong.intValue() : 0;
        if (userCount > 0) {
            throw new RuntimeException("该组织下存在用户，无法删除");
        }
        
        organizationMapper.deleteById(id);
    }
    
    /**
     * 批量删除组织
     */
    public void deleteOrganizations(List<String> ids) {
        for (String id : ids) {
            deleteOrganization(id);
        }
    }
    
    /**
     * 获取子组织列表
     */
    public List<Organization> getChildrenOrganizations(String parentId) {
        return organizationMapper.selectByParentId(parentId);
    }
    
    /**
     * 检查是否有子组织
     */
    public boolean hasChildren(String id) {
        return organizationMapper.hasChildren(id);
    }
    
    /**
     * 获取组织路径
     */
    public List<Organization> getOrganizationPath(String id) {
        return organizationMapper.selectPath(id);
    }
    
    /**
     * 获取组织下的用户数量
     */
    public int getUserCount(String id) {
        Long userCountLong = organizationMapper.selectUserCount(id);
        return userCountLong != null ? userCountLong.intValue() : 0;
    }
    
    /**
     * 移动组织
     */
    public void moveOrganization(String id, String newParentId) {
        Organization organization = organizationMapper.selectById(id);
        if (organization == null) {
            throw new RuntimeException("组织不存在");
        }
        
        // 检查是否形成循环引用
        if (StringUtils.hasText(newParentId) && isCircularReference(id, newParentId)) {
            throw new RuntimeException("不能将组织移动到其子组织下");
        }
        
        Organization updateOrg = new Organization();
        updateOrg.setId(id);
        updateOrg.setParentId(newParentId);
        updateOrg.setUpdatedAt(LocalDateTime.now());
        
        organizationMapper.updateById(updateOrg);
    }
    
    /**
     * 检查组织名称是否可用
     */
    public boolean isNameAvailable(String name, String parentId, String excludeId) {
        if (!StringUtils.hasText(name)) {
            return false;
        }
        
        Organization existing = organizationMapper.selectByName(name);
        if (existing == null) {
            return true;
        }
        
        // 如果是更新操作，排除自己
        if (StringUtils.hasText(excludeId) && existing.getId().equals(excludeId)) {
            return true;
        }
        
        // 检查是否在同一父级下重名
        return !Objects.equals(existing.getParentId(), parentId);
    }
    
    /**
     * 更新最后同步时间
     */
    public void updateLastSyncAt(String id, LocalDateTime lastSyncAt) {
        organizationMapper.updateLastSyncAt(id);
    }
    
    /**
     * 获取组织统计信息
     */
    public Map<String, Object> getOrganizationStatistics() {
        Map<String, Object> statistics = new HashMap<>();
        
        // 总组织数
        long totalCount = organizationMapper.selectCount(null, null);
        statistics.put("totalCount", totalCount);
        
        // 根组织数
        List<Organization> rootOrgs = organizationMapper.selectRootOrganizations();
        statistics.put("rootCount", rootOrgs.size());
        
        // 最大层级深度
        int maxDepth = calculateMaxDepth();
        statistics.put("maxDepth", maxDepth);
        
        // 有用户的组织数
        int orgsWithUsers = countOrganizationsWithUsers();
        statistics.put("orgsWithUsers", orgsWithUsers);
        
        return statistics;
    }
    
    /**
     * 计算最大层级深度
     */
    private int calculateMaxDepth() {
        List<Organization> allOrgs = organizationMapper.selectAll();
        int maxDepth = 0;
        
        for (Organization org : allOrgs) {
            if (org.getParentId() == null) {
                int depth = calculateDepth(allOrgs, org.getId(), 1);
                maxDepth = Math.max(maxDepth, depth);
            }
        }
        
        return maxDepth;
    }
    
    /**
     * 递归计算深度
     */
    private int calculateDepth(List<Organization> allOrgs, String parentId, int currentDepth) {
        int maxDepth = currentDepth;
        
        for (Organization org : allOrgs) {
            if (Objects.equals(org.getParentId(), parentId)) {
                int depth = calculateDepth(allOrgs, org.getId(), currentDepth + 1);
                maxDepth = Math.max(maxDepth, depth);
            }
        }
        
        return maxDepth;
    }
    
    /**
     * 统计有用户的组织数
     */
    private int countOrganizationsWithUsers() {
        List<Organization> allOrgs = organizationMapper.selectAll();
        int count = 0;
        
        for (Organization org : allOrgs) {
            Long userCountLong = organizationMapper.selectUserCount(org.getId());
            int userCount = userCountLong != null ? userCountLong.intValue() : 0;
            if (userCount > 0) {
                count++;
            }
        }
        
        return count;
    }
}